
#ifndef __KEY_H__
#define __KEY_H__

/*
按键滤波时间 50ms, 单位 10ms。
只有连续检测到 50ms 状态不变才认为有效，包括弹起和按下两种事件
即使按键电路不做硬件滤波，该滤波机制也可以保证可靠地检测到按键事件
*/
#define KEY_FILTER_TIME		5
#define KEY_LONG_TIME		100 /* 单位 10ms， 持续 1 秒，认为长按事件 */

#define  ENABLE		1
#define  DISABLE	0

/*
	Key驱动使用的FIFO队列接口，函数指针定义
	可自行设计该函数，也可引用使用fifo.c函数
*/
typedef unsigned int (*FifoLenForKey)(void);
typedef unsigned int (*FifoPutForKey)(unsigned char *buf, unsigned int len);
typedef unsigned int (*FifoGetForKey)(unsigned char *buf, unsigned int len);

typedef struct
{
	FifoLenForKey	Len; 
	FifoPutForKey	Put; 
	FifoGetForKey	Get;
}FifoForKey_t;

/*按键相关函数*/
typedef unsigned char	(*IsKeyDownFunc)(void);

/*按键定义枚举，修改程序需要添加或删去相应序号*/
typedef enum
{
	KEY_1,
	KEY_2,
	KEY_MAX,
}KEY_TYPE;

//按键状态
typedef enum
{
	KEY_UP,			/* 键弹起 */
	KEY_DOWN,		/* 键按下 */
	KEY_LONG,		/* 键长按 */
}KEY_STATUS_ENUM;

/*
	按键实现基本逻辑
	1.按键是否按下；
	2.按键抖动滤波；
	3.长按判断；
	4.持续按键是否连续发送信号；
*/

typedef struct
{
	unsigned char State:2;	//按键状态
	unsigned char Index:6;	//按键序号
}KeyInfo_t;

struct KEY_T
{
	struct KEY_T *next;					/* 指向下一个按键结构体 */
	IsKeyDownFunc Fuc;					/* 下面是一个函数指针，指向判断按键手否按下的函数  1表示按下*/
	unsigned char  ShortCount; 			/* 短按计数器,滤波器计数器 */
	unsigned char  ShortTimeLimit; 		/* 判断短按按键的时间门限 */
	unsigned short LongCount;			/* 长按计数器 */
	unsigned short LongTimeLimit;		/* 判断持续按键的时间门限, 0 表示不检测长按 */	
	unsigned char  RepeatCount;			/* 连续按键计数器 */
	unsigned char  RepeatTimeLimit;		/* 连续按键，多次触发周期，0表示不触发，n代表识别长按后每n次后发送一次按下信号 */
	KeyInfo_t  KeyInfo;					/* 按键当前状态 */
};

//key专用fifo函数注册
void FifoFuncRegister(FifoLenForKey FifoLen, FifoPutForKey FifoPut, FifoGetForKey FifoGet);
void KeyAdd(KEY_TYPE index, unsigned char ischecklongpush, unsigned char ischeckrepeat, IsKeyDownFunc fuc);
//10MS周期调用
void KeyHandle(void);
//获取按键状态
char GetKeyInfo(KeyInfo_t *KeyInfo);
#endif

